A Memory Management Unit (MMU) may refer to a hardware block that translates virtual addresses of memory seen by a central processing unit (CPU) into physical addresses of volatile memory. A MMU typically has the following purposes.
When an operating system (OS) has two levels of privileges, such as a privileged level and a user level, the MMU may be reconfigured by the OS kernel, which may be running in privileged mode, when switching from one user process to another. This enables the providing of fully virtual memory maps to user processes, so that different user processes may see the same libraries of functions at different virtual addresses, and also so that user processes may see a limited part of memory, and may not be able to see the OS kernel data or code, or the data or code of other processes. This purpose of a MMU may thus be oriented towards security.
In addition, OS applications may include the allocation of big memory buffers for application processing. As memory allocation and de-allocation operations may occur often in an OS, the occupation of memory by the OS may quickly reach a fragmented state, in which there are many allocated memory chunks of various sizes, separated by many non-allocated chunks. In this situation, if the OS was working with physical memory, it might soon after startup be unable to allocate big contiguous buffers. The MMU may allocate a large virtual contiguous memory buffer to an OS application, but that memory buffer may in fact span several small chunks in physical memory. The MMU may manage translation of virtual contiguous addresses of the memory buffer into addresses of sparsely located chunks in physical memory. This purpose of a MMU may thus be oriented towards addressing the issue of fragmentation memory by hiding it.
To summarize, an MMU may translate virtual addresses (VA) in a VA space into physical addresses (PA) in a PA space, with a twofold goal of being able to provide contiguous memory buffers to applications running on the OS, and being able to isolate VAs seen by different applications running on the OS.
The VA memory is split into memory pages, for which there are different possible granularities, such as a memory page of small size such as 4 KB and a memory page of a larger size, such as 1 MB. For each page, access rights and information for how the page translates, i.e. maps, to PA are defined. This information for each page is gathered inside a MMU table in the form of a respective memory page entry that also may be referred to as a page descriptor, or page table entry (PTE), depending on terminology used.
FIG. 1A schematically illustrates an example of such a memory page entry. In the shown example, there is included a VA start address, a memory page size, an offset relative to a base address of the PA, and access rights. The MMU table is stored in memory, which can be volatile, such as random access memory (RAM), or non-volatile, such as read only memory (ROM), depending on whether the MMU table is to be modified dynamically during execution. If the access rights and translation are the same for large pages as for the small pages it contains, the MMU table may not contain memory page entries for the small pages, and it may instead contain an entry for the large page.
FIG. 1B schematically illustrates the principle of MMU address translations. Note that there are two addresses VA#1 that belong to different processes, such as different applications, running on the OS, but that map to different PAs, here PA#1 and PA#2 respectively. In practice it may be the OS that, based on which process is making a request for memory access, controls the MMU so as to use correct translations for that process, and the MMU may help ensure that different processes map to different PAs.
FIG. 1C schematically illustrates, in a simplified manner, a one-stage MMU 100, i.e. a MMU that uses one stage of address translation as described above. The one-stage MMU 100 is associated with, and has access to, a MMU table 102, such as described above. However, note that depending on implementation, the MMU table 102 may be physically located in memory outside the one-stage MMU 100. The one-stage MMU is associated with, and has access, to a cache memory 104, i.e. a fast access memory, associated with the MMU table 102, that is for storing memory page entries of the MMU table so as to enable quicker access by the MMU 100 than from the MMU table 102. For example, VAs likely to be requested next may be estimated, and memory page entries thereof may be put in the cache memory 104 to be accessible, if there is a later, i.e. further, request relating to a VA that is included in any of the memory page entries in the cache memory. A so called translation lookaside buffer (TLB) is an example of such memory cache of the MMU 100.
With the latest generations of processors, two-stage MMUs have been introduced. The purpose of a two-stage MMU is to be able to support multiple OSes running in parallel on the same hardware, which may be referred to as virtualization or isolation, in a way such that each OS has the impression of managing its own physical memory, peripherals and registers. Each such OS may be referred to as a guest OS. Each guest OS manages a contiguous intermediate physical address (IPA) space, which it may see as its own PA space, and, as before, uses VAs for applications running on the OS.
Hence each guest OS may use a first MMU stage that relates to VA-to-IPA translations, and that is similar to the stage in a conventional one-stage MMU that relates to VA-to-PA translations as described above. In order to manage the multiple OSes in parallel, each IPA may be remapped to a respective PA of physical memory, typically RAM. The VA-to-IPA stage may be controlled by the respective guest OS, while the IPA-to-PA stage may be controlled by what is referred to as a virtualization layer, or hypervisor, that is common for the Guest OSes running in parallel on the same hardware. A virtualization layer, or hypervisor, is an independent binary, running in a privileged mode, and manages memory and peripheral access rights for the guest OSes. The role is to mask the existence of multiple OSes and therefore their presence to each other. The hypervisor layer may be started before the guest OSs by a platform boot loader.
FIG. 2 schematically illustrates the principle of two-stage address translations in a two-stage MMU. Two guest OSes, guest OSX and guest OSY are shown to illustrate the principle. Compare, for example, with the one stage address translations schematically illustrated in FIG. 1b. When a process, such as an application running on one guest OS, say guest OSX, requests a VA, say VAX#1, the page entry for this VA from a first MMU table of a first stage, i.e. VA-to-IPA stage, is parsed, and the corresponding IPA is found, IPAX#1. This first stage corresponds to the address translations discussed above in connection with FIG. 1B. A similar procedure is used in a second stage, i.e. in an IPA-to-PA stage, of address translation to find the PA, here PA#4, to which the IPA, here IPAX#1, maps according to a second MMU table. Note that IPAX#1 and IPAY#1 may be the same address but kept by the MMU in the second stage of address translation from knowing to which guest OS a requested IPA pertains. Similarly, different applications may use the same VA in the first stage address translations. In practice it may be the virtualization layer that, based on which OS is making a request for translation, controls the MMU to use correct translations for that OS, and the MMU helps ensure that different OSes map to different PAs.
One potential issue related to two-stage MMUs, as may be realized from the above, is the increased MMU table management and additional operations that may be carried out for each memory access request in order to be able to retrieve and use the translation information desired. This makes it difficult to accomplish efficient implementations of two-stage MMUs. Therefore, further development in the area of memory management units is desired.